#ifndef __BEEP_H__
#define __BEEP_H__

#include "typedef.h"

#ifdef _12F629
    #define BEEP_TRIS       TRISIO4
    #define BEEP_PORT       GPIO4
    #define BEEP_PIN        GPIO4
#endif

#ifdef _12F683
    #define BEEP_TRIS       TRISIO2
    #define BEEP_PORT       GP2
    #define BEEP_PIN        GP2
#endif


#define FOSC                    _XTAL_FREQ
//#define TOSC                    (1000000 / FOSC)

#define TIMER2_PRESCALER        16
#define TIMER2_COUNT_PERIOD     ( 4 * TIMER2_PRESCALER * 1000000 / FOSC )

#define PWM_ALARM_PERIOD_MIN    250
#define PWM_ALARM_PERIOD_MAX    1100
#define PWM_BEEP_PERIOD         985
#define PWM_BELL_BING_PERIOD    1052
#define PWM_BELL_BONG_PERIOD    1356

// PWM period = (PR2 + 1) * 4 * Tosc * Timer2 prescale
// Pulse width = (CCPR1L:CCP1CON<5:4>) * Tosc * TMR2 Prescale
#define PWM_ALARM_MIN_PR2       ( ( PWM_ALARM_PERIOD_MIN / TIMER2_COUNT_PERIOD ) - 1 )
#define PWM_ALARM_MIN_CCPR1L    ( ( 2 * PWM_ALARM_PERIOD_MIN / TIMER2_COUNT_PERIOD ) / 4 )
#define PWM_ALARM_MIN_DC1B      ( ( 2 * PWM_ALARM_PERIOD_MIN / TIMER2_COUNT_PERIOD ) % 4 )
#if (PWM_ALARM_MIN_PR2 > 255)
    #warning "PWM_ALARM_MIN_PR2 is overflow";
#endif

#define PWM_ALARM_MAX_PR2       ( ( PWM_ALARM_PERIOD_MAX / TIMER2_COUNT_PERIOD ) - 1 )
#define PWM_ALARM_MAX_CCPR1L    ( ( 2 * PWM_ALARM_PERIOD_MAX / TIMER2_COUNT_PERIOD ) / 4 )
#define PWM_ALARM_MAX_DC1B      ( ( 2 * PWM_ALARM_PERIOD_MAX / TIMER2_COUNT_PERIOD ) % 4 )
#if (PWM_ALARM_MAX_PR2 > 255)
    #warning "PWM_ALARM_MAX_PR2 is overflow";
#endif

#define PWM_BEEP_PR2            ( ( PWM_BEEP_PERIOD / TIMER2_COUNT_PERIOD ) - 1 )
#define PWM_BEEP_CCPR1L         ( ( 2 * PWM_BEEP_PERIOD / TIMER2_COUNT_PERIOD ) / 4 )
#define PWM_BEEP_DC1B           ( ( 2 * PWM_BEEP_PERIOD / TIMER2_COUNT_PERIOD ) % 4 )
#if (PWM_BEEP_PR2 > 255)
    #warning "PWM_BEEP_PR2 is overflow";
#endif

#define PWM_BELL_BING_PR2       ( ( PWM_BELL_BING_PERIOD / TIMER2_COUNT_PERIOD ) - 1 )
#define PWM_BELL_BING_CCPR1L    ( ( 2 * PWM_BELL_BING_PERIOD / TIMER2_COUNT_PERIOD ) / 4 )
#define PWM_BELL_BING_DC1B      ( ( 2 * PWM_BELL_BING_PERIOD / TIMER2_COUNT_PERIOD ) % 4 )
#if (PWM_BELL_BING_PR2 > 255)
    #warning "PWM_BELL_BING_PR2 is overflow";
#endif
    
#define PWM_BELL_BONG_PR2       ( ( PWM_BELL_BONG_PERIOD / TIMER2_COUNT_PERIOD ) - 1 )
#define PWM_BELL_BONG_CCPR1L    ( ( 2 * PWM_BELL_BONG_PERIOD / TIMER2_COUNT_PERIOD ) / 4 )
#define PWM_BELL_BONG_DC1B      ( ( 2 * PWM_BELL_BONG_PERIOD / TIMER2_COUNT_PERIOD ) % 4 )
#if (PWM_BELL_BONG_PR2 > 255)
    #warning "PWM_BELL_BONG_PR2 is overflow";
#endif


//#define BEEP_BEEP
    #define BEEP_SHORT_TIMER            ( 60 / SYSTEM_TICK_PERIOD )
    #define BEEP_BLOCKING_SHORT_TIMER   60

//#define BEEP_BEEP_LONG
    #define BEEP_LONG_TIMER             ( 200 / SYSTEM_TICK_PERIOD )
    #define BEEP_BLOCKING_LONG_TIMER    200

//#define BEEP_BEEP2
    #define BEEP2_ON_TIMER             ( 60 / SYSTEM_TICK_PERIOD )
    #define BEEP2_OFF_TIMER            ( 60 / SYSTEM_TICK_PERIOD )
    #define BEEP2_ON_BLOCKING_TIMER    60
    #define BEEP2_OFF_BLOCKING_TIMER   60

//#define BEEP_BEEP3
    #define BEEP3_ON_TIMER             ( 60 / SYSTEM_TICK_PERIOD )
    #define BEEP3_OFF_TIMER            ( 60 / SYSTEM_TICK_PERIOD )
    #define BEEP3_ON_BLOCKING_TIMER    60
    #define BEEP3_OFF_BLOCKING_TIMER   60

//#define BEEP_ALARM
    #define ALARM_TIMER             ( 25000 / SYSTEM_TICK_PERIOD )
    #define ALARM_IDLE_TIMER        ( ALARM_TIMER + ( 3000 / SYSTEM_TICK_PERIOD ) )

//#define BEEP_BELL
    #define BELL_TIMER1             ( 300 / SYSTEM_TICK_PERIOD )
    #define BELL_TIMER2             ( BELL_TIMER1 + ( 700 / SYSTEM_TICK_PERIOD ) )
    #define BELL_TIMER3             ( BELL_TIMER2 + ( 500 / SYSTEM_TICK_PERIOD ) )
    #define BELL_BLOCKING_TIMER1    300
    #define BELL_BLOCKING_TIMER2    700
    #define BELL_BLOCKING_DELAY     3000
        
typedef enum _eBeepType
{
    BEEP_BEEP,
    BEEP_BEEP_LONG,
    BEEP_BEEP2,
    BEEP_BEEP3,
    BEEP_ALARM,
    BEEP_BELL,
    BEEP_BELL_ON_LED
} eBeepType;
        

typedef enum _ePulseType
{
    NOT_CHANGE,
    INC_TYPE,
    DEC_TYPE
} ePulseType;

extern volatile U8              v_ReloadTimer2;
extern volatile ePulseType      v_PulseType;

#define Beep_SetPeriod(timeReload)          PR2 = v_ReloadTimer2 = timeReload; TMR2 = 0; TMR2IE = 0
#define Beep_SetPeriodInterrupt(timeReload) PR2 = v_ReloadTimer2 = timeReload; TMR2 = 0; TMR2IE = 1
#define Beep_TurnOnPwm()                    TMR2ON = 1
#define Beep_TurnOffPwm()                   TMR2ON = 0
//#define Beep_SetPeriod(a)                   PR2 = a; v_ReloadTimer2 = a
#define Beep_GetPeriod()                    v_ReloadTimer2
#define Beep_IncPeriod()                    PR2 = ++v_ReloadTimer2
#define Beep_DecPeriod()                    PR2 = --v_ReloadTimer2
#define Beep_SetPulseType(a)                v_PulseType = a
#define Beep_GetPulseType()                 v_PulseType
                                             
void Beep_InitReset( void );                 
void Beep_OnAlarm(void);
void Beep_OnBeep(void);
void Beep_OnBellBing(void);
void Beep_OnBellBong(void);
void Beep_TurnOff(void);
#ifdef TESTING_MODE
void Beep_SetBeepType( eBeepType iBeepType);
#endif
#endif  //__BEEP_H__